/* License Notice:
**
** This program is free software: you can redistribute it and/or modify
**    it under the terms of the GNU General Public License as published by
**    the Free Software Foundation, either version 3 of the License, or
**    (at your option) any later version.
** This program is distributed in the hope that it will be useful,
**   but WITHOUT ANY WARRANTY; without even the implied warranty of
**   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
**   GNU General Public License for more details.
** You should have received a copy of the GNU General Public License
**   along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

/**
 * @file game_object.cpp
 * @author TooOld2Rock'nRoll
 * @see game_object.hpp
 */
/*---- Includes ----*/
#include "interfaces/game_object.hpp"

#include "toolbox/debug.h"



/*---- Global Variables ----*/


/*---- Methods Implementation ----*/
/**
 * @brief GameObject base Constructor.
 *
 * @param domain_id - the domain identification to use when loading resources.
 * @param sh - optional Shader to be used on all render operations.
 * @param sprite_count - how many sprites should be pre-allocated.
 *
 * @throws std::invalid_argument - if sprite_count is zero (it makes no sense!).
 */
GameObject::GameObject (DomainID_t domain_id, Shader *sh, unsigned sprite_count) :
    ui_sprite_count(sprite_count), _res_domain_id(domain_id), obj_shader(sh)
{
    _debug (TRACE, "::%s (domain_id=%u, s_count=%u)", __FUNCTION__, domain_id, sprite_count);

    if (sprite_count == 0)
        throw std::invalid_argument (fmt::format ("{0}:{1} - sprite count must be > 0!", __LINE__, __FILE__));

    this->p_resource_manager = &ResourceManager::instance ();

    this->ap_sprite_list = new Sprite2D[sprite_count] ();
}//End Contructor

/**
 * @brief Destructor.
 */
GameObject::~GameObject ()
{
    _debug (TRACE, "::%s ()", __FUNCTION__);

    delete[] (this->ap_sprite_list);
}//End Destructor

/**
 * @brief Helper method, sets a texture to be used by all the Sprites in the GameObject.
 * @remark Most of the times, the GameObject itself will be responsible for loading and managing itsown resources.
 *
 * @param t - The texture reference to create sprites with.
 */
void GameObject::setTexture (Texture *t)
{
    int i = 0;

    _debug (TRACE, "::%s ()", __FUNCTION__);

    for (i = this->ui_sprite_count; i--; )
        this->ap_sprite_list[i].setTexture (t);
}//End setTexture ()


/**
 * @brief @brief Gets a reference to a specific sprite.
 *
 * @param index - sprite index.
 *
 * @return Reference to the desired sprite.
 *
 * @throws std::runtime_error - if the sprite list was not initialized yet for some reason...
 * @throws std::out_of_range - if the sprite index is greater than the max number of sprites supported.
 */
Sprite2D& GameObject::getSprite (unsigned index) const
{
    _debug (TRACE, "::%s (index=%u)", __FUNCTION__, index);

    if (!this->ap_sprite_list)
        throw std::runtime_error (fmt::format ("{0}:{1} - GameObject has no sprite list allocated!", __LINE__, __FILE__));
    else if (index >= this->ui_sprite_count)
        throw std::out_of_range (fmt::format ("{0}:{1} - Sprite out of range, {2} of {3}!", __LINE__, __FILE__, index, this->ui_sprite_count - 1));

    return this->ap_sprite_list[index];
}//End getSprite ()

